﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Deflection
{
    class Enemy : GameObject
    {

        public Vector2 direction = Vector2.Zero;

        public Vector2 movementTarget = Vector2.Zero;

        protected float speed = GameParameters.BASE_ENEMY_SPEED;
        public EnemyType Type { get; set; } 
        public bool partOfSuper = false;
        public bool isCore = false;
        public bool inPlace = false;
        public float scale = 1;
        public Path path;
        public int pathNodeIndex = 0;
        public Player killer = null;

        public Formation formation;
        public int formationNodeIndex = 0;

        public Color Color { get; set; }

        public enum EnemyState
        {
            Spawning,
            Alive,
            Dying,
            Dead

        }

        public SubEnemies SubEnemies { get; set; }
        public ParticleSystem ParticleSystem { get; set; }

        public Texture2D Texture { get; set; }

        public EnemyState State { get; set; }
        public Random rand;

        public enum EnemyType
        {
            SquareEnemy = 0, // obstacle        
            TriangleEnemy,
            HexagonEnemy,
            SuperSquare,
            SuperTriangle,// group of smaller enemies
            SuperHexagon
            // shoots at random position
            // shotgun
            // shoots straight line horizontal
            // stream shot
            // vertical straight shot
        }

        public enum EnemyScore
        {
            SquareEnemy = 10,    // 10
            TriangleEnemy = 10,      // 10
            HexagonEnemy = 10,       // 10
            SuperSquare = 20,        // 20
            SuperTriangle = 20,      // 20
            SuperHexagon = 20        // 20

        }

        //public static Texture2D EnemySprite { get; set; }



        public Enemy(Vector2 Position, Texture2D texture, Color color) : base(Position)
        {
            Alive = true;
            State = EnemyState.Alive;
            Color = color;
            Texture = texture;

            sizeInPixels = new Vector2(scale * texture.Bounds.Width, scale * texture.Bounds.Height);
            // make it go left
            Velocity = new Vector2(-3.0f, 0.0f);
            rand = new Random((int)position.X * (int)position.Y);
            ParticleSystem = new ParticleSystem(Position, Texture, Color, 0.25f);
            ParticleSystem.MaxLife = 40;
            ParticleSystem.Drawing = true;
            CreateSubEnemies();
        }

        public Enemy(Vector2 position)  : base(position)
        {
            Alive = true;
            State = EnemyState.Alive;
            Color = Microsoft.Xna.Framework.Color.White;

            // make it go left
            Velocity = new Vector2(-3.0f, 0.0f);
        }

        public override void Update(GameTime gameTime)
        {
            switch (State)
            {
                case EnemyState.Spawning:
                    State = EnemyState.Alive;
                    break;
                case EnemyState.Alive:
                    // Check if it has a formation to follow
                    if (HasFormation())
                    {
                        Position = formation.GetCurrentPositionInFormation(formationNodeIndex);
                    }
                    else
                    {
                        // Make the enemy go to the left

                        Position += Velocity;
                        
                    }
                    if (position.Y < Texture.Bounds.Height / 2)
                    {
                        position.Y++;
                    }
                    if (position.Y > GameParameters.SCREEN_SIZE.Y - Texture.Bounds.Height / 2)
                    {
                        position.Y--;
                    }
                    // Update its particles
                    if (Type != EnemyType.SuperSquare)
                    {
                        ParticleSystem.Position = Position;
                        ParticleSystem.Update(gameTime);
                        // Update the subenemies
                        SubEnemies.Position = Position;
                    }
                    break;
                case EnemyState.Dying:
                    if (Type != EnemyType.SuperSquare)
                    {
                        ParticleSystem.Spawning = false;
                        ParticleSystem.Position = Position;
                        ParticleSystem.Update(gameTime);
                        SubEnemies.Update(gameTime);
                    }

                    // Make the enemy non-collideable as  its dying
                    IsCollidable = false;


                    if (SubEnemies.Finished)
                    {
                        State = EnemyState.Dead;
                    }

                    break;
                case EnemyState.Dead:
                    Die();
                    break;
            }
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            switch (State)
            {
                case EnemyState.Spawning:
                    break;
                case EnemyState.Alive:
                    // Draw the enemy
                    spriteBatch.Draw(Texture, Position, null, Color, Rotation, new Vector2(Texture.Bounds.Center.X, Texture.Bounds.Center.Y), scale, SpriteEffects.None, 0);

                    // Draw its particles
                    ParticleSystem.Draw(gameTime, spriteBatch);
                    break;
                case EnemyState.Dying:
                    int score = 0;
                    switch (this.Type)
                    {
                        case Enemy.EnemyType.SquareEnemy:
                            score = (int)EnemyScore.SquareEnemy;
                            if (isCore)
                            {
                                score = (int)EnemyScore.SuperSquare;
                            }
                            break;
                        case Enemy.EnemyType.TriangleEnemy:
                            score = (int)EnemyScore.TriangleEnemy;
                            if (isCore)
                            {
                                score = (int)EnemyScore.SuperTriangle;
                            }
                            break;
                        case Enemy.EnemyType.HexagonEnemy:
                            score = (int)EnemyScore.HexagonEnemy;
                            if (isCore)
                            {
                                score = (int)EnemyScore.SuperHexagon;
                            }
                            break;
                    }
                    Color color;
                    if (killer != null)
                    {
                        color = killer.color;
                    }
                    else
                    {
                        color = Color.Orange;
                    }
                    
                    Vector2 textSize = GameParameters.GAME_FONT.MeasureString(score.ToString());
                    spriteBatch.DrawString(GameParameters.GAME_FONT, score.ToString(), Position, Color.Lerp(color, Color.Black, 0.15f), 0f, textSize, 0.45f, SpriteEffects.None, 0f);
                    position.Y += rand.Next(-5, 6);
                    position.X += rand.Next(-5, 6);
                    ParticleSystem.Draw(gameTime, spriteBatch);
                    // Draw the sub enemies (parts)
                    SubEnemies.Draw(gameTime, spriteBatch);
                        
                    break;
                case EnemyState.Dead:
                    break;
            }
        }

        public virtual void CreateSubEnemies()
        {
            SubEnemies = new SubEnemies(Position - new Vector2(Texture.Bounds.Center.X, Texture.Bounds.Center.Y), Texture, Color, 3);
            SubEnemies.MaximumParticles = (3 * 3);
            SubEnemies.SpawnRate = 1;
            SubEnemies.Spawning = true;
            SubEnemies.Drawing = true;
            SubEnemies.Active = true;
        }

        /// <summary>
        /// Handles the movement of the enemey
        /// </summary>
        public virtual void Move()
        {

        }

        /// <summary>
        /// Gets the direction vector
        /// </summary>
        /// <param name="vector"></param>
        public void FindDirection(Vector2 vector)
        {
            Vector2 dir = Vector2.Subtract(vector, this.Position);
            dir.Normalize();
            //dir *= speed;
            dir = Vector2.Multiply(dir, speed);

            this.direction = dir;            
        }

        public Vector2 CreateMovementTarget()
        {
            Random rand = new Random();
            return new Vector2(rand.Next(0, (int)GameParameters.SCREEN_SIZE.X), rand.Next(0, (int)GameParameters.SCREEN_SIZE.Y));

        }


        public float GetDistanceToMovementTarget()
        {
            return GetDistance(Position, this.movementTarget);
        }

        public float GetDistance(Vector2 vector1, Vector2 vector2)
        {
            return Vector2.Distance(vector1, vector2);
        }

        public bool HasTarget()
        {
            if (movementTarget == Vector2.Zero)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Checks if the enemy has a path
        /// </summary>
        /// <returns>True if the enemy has a path</returns>
        public bool HasPath()
        {
            if (this.path == null)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Checks if the enemy has a formation
        /// </summary>
        /// <returns>True if the enemy has a formation</returns>
        public bool HasFormation()
        {
            if (this.formation == null)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// Handles the firing of the enemy
        /// </summary>
        public virtual void Fire(GameTime gameTime)
        {

        }

        public override bool IsOffscreen()
        {
            if (this.position.Y < 0 - Texture.Height)
            {
                return true;
            }
            if (this.position.X < -150)
            {
                return true;
            }
            if (this.position.Y > GameParameters.SCREEN_SIZE.Y + Texture.Height)
            {
                return true;
            }
            // So that enemies can spawn off the right side of the screen
            /*if (this.position.X > GameParameters.SCREEN_SIZE.X + TestEnemy2.EnemySprite.Width)
            {
                return true;
            }*/
            return false;
        }

        public override void Die()
        {
            State = EnemyState.Dead;
            base.Die();
        }



    }
}
